﻿#include "netManger_tcp.h"


netManger_tcp::netManger_tcp(std::function<void (QTcpSocket *)> localReadyReadFun, std::function<void (QTcpSocket *)> disConnectFun)
    :event_localReadyRead(localReadyReadFun),event_disConnected(disConnectFun)
{
    lifeTimer = new QTimer;
    QObject::connect(lifeTimer,&QTimer::timeout,[=](){ //绑定心跳计时器
        for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){
            if(i->socket != nullptr && i->signNumber != 0 && i->signNumber < this->signNumber){
                i->socket->close(); //回收套接字信息
                i->serverAddress = "";
                i->localPort = 0;
                i->signNumber = 0; //标明被回收，不需要清理
            }
        }
        this->signNumber = this->lifeNumber; //更新标记信息到最新的值
    });
    lifeTimer->start(240000); //4分钟清理回收一次

}

netManger_tcp::~netManger_tcp()
{
    for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){
        if(i->socket != nullptr){
            delete i->socket;
        }
    }
}



//添加服务器用户到用户列表
QTcpSocket *netManger_tcp:: addUser(QString serverAddress, uint16_t localPort)
{

    QTcpSocket* t_s = this->getSocket(serverAddress); //检查本地是否已经存在了
    if(t_s == nullptr){
        //判断容器内部是否已经满
        if(this->userList.length() >= USERMAX){
            //如果已经满了，则在内部查找是否存在空闲的对象
            for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){
                if(i->serverAddress.isEmpty() && i->socket != nullptr && i->localPort == 0){
                    i->socket->close();
                    i->serverAddress = serverAddress;
                    i->localPort = localPort;
                    i->signNumber = ++this->lifeNumber;
                    return i->socket;
                }

                //对已经断开连接的Socket进行复用
                if(i->socket != nullptr && i->socket->state() == QAbstractSocket::UnconnectedState){
                    i->socket->close();
                    i->serverAddress = serverAddress;
                    i->localPort = localPort;
                    i->signNumber = ++this->lifeNumber;
                    return i->socket;
                }

            }
            return nullptr; //大于等于最大用户限制后，不添加用户
        }
        else{ //没有满，则添加新成员
            t_s = new QTcpSocket;
            QAbstractSocket::connect(t_s,&QTcpSocket::readyRead,[=]{
                if(event_localReadyRead != nullptr){
                    this->event_localReadyRead(t_s);
                }
            });

            QAbstractSocket::connect(t_s,&QTcpSocket::disconnected,[=]{
                if(event_disConnected != nullptr){
                    this->event_disConnected(t_s);
                }
            });

            //t_s->connectToHost(QHostAddress("127.0.0.1"),localPort);
            this->userList.append({serverAddress,localPort,t_s,++this->lifeNumber});
        }
    }
    return t_s;
}


//移除用户
bool netManger_tcp::removeUser(QString serverAddress)
{
    for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){
        if(i->serverAddress == serverAddress){
            i->socket->close();
            i->serverAddress = "";
            i->localPort = 0;
            i->signNumber = 0; //标明被回收，不需要清理
            return true;
        }
    }
    return false;
}

bool netManger_tcp::removeUser(QTcpSocket* socket)
{
    for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){
        if(i->socket == socket){
            i->socket->close();
            i->serverAddress = "";
            i->localPort = 0;
            i->signNumber = 0; //标明被回收，不需要清理
            return true;
        }
    }
    return false;
}



//获取用户数量
uint32_t netManger_tcp::getUserNumber()
{
    uint32_t t_num = 0;
    for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){
        if(!i->serverAddress.isEmpty()){
            t_num++;
        }
    }
    return t_num;
}



//根据Socket对象，返回服务器标记
QString netManger_tcp::getServerAddress(QTcpSocket* socket)
{
    for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){
        if(i->socket == socket){
            i->signNumber = ++this->lifeNumber;
            return i->serverAddress;
        }
    }
    return "";
}


//工具标记，获取Socket对象
QTcpSocket *netManger_tcp::getSocket(QString address)
{
    for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){
        if(i->serverAddress == address && i->socket != nullptr){
            i->signNumber = ++this->lifeNumber;
            return i->socket;
        }
    }
    return nullptr;
}


//清理全部的接口
void netManger_tcp::clear()
{
    for(QVector<socketMsg>::iterator i = this->userList.begin(); i < this->userList.end(); i++){
        if(!i->serverAddress.isEmpty()){
            i->socket->close();
            i->serverAddress = "";
            i->localPort = 0;
            i->signNumber = 0;
        }
    }
}


//客户连接，云服务到本地
bool netManger_tcp::event_connect(QString serverAddress, uint16_t localPort)
{
    QTcpSocket* t_s = this->addUser(serverAddress,localPort);    //添加用户，如果用户已经存在，则返回存在的套接字
    if(t_s == nullptr) return false; //添加用户失败，则直接返回假
    t_s->close(); //先尝试断开连接
    t_s->connectToHost(QHostAddress("127.0.0.1"),localPort); //本地连接
    return t_s->waitForConnected();
}


//收到数据，云服务到本地
bool netManger_tcp::event_readyRead(QString serverAddress, QByteArray data)
{
    QTcpSocket* t_s = this->getSocket(serverAddress); //
    if(t_s == nullptr) return false;
    return t_s->write(data) != -1;   //收到数据则转发到本地的服务器
}


//客户离开，云服务到本地
bool netManger_tcp::event_disConnect(QString serverAddress)
{
    return this->removeUser(serverAddress);
}

